﻿using PowerEV3.Core.Controls;
using PowerEV3.Core.Properties;
using Lego.Ev3.Core;
using Lego.Ev3.Desktop;
using Microsoft.Office.Core;
using Microsoft.Office.Interop.Excel;
using System;
using System.Threading.Tasks;
using System.Windows.Controls;
using VSTOContrib.Core;
using VSTOContrib.Core.RibbonFactory.Interfaces;
using VSTOContrib.Core.RibbonFactory.Internal;
using VSTOContrib.Core.Wpf;
using Factory = Microsoft.Office.Tools.Factory;

namespace PowerEV3.Core.Contexts
{
    public class RobotViewModel : OfficeViewModelBase, IRibbonViewModel, IRegisterCustomTaskPane
    {
        bool panelShown, ribbonVisible;
        ICustomTaskPaneWrapper ev3TaskPane;
        Workbook workbook;

        public RobotViewModel()
        {
        }


        public IRibbonUI RibbonUi { get; set; }

        public Factory VstoFactory { get; set; }

        private Brick ev3Brick;

        private MainPanel mainPanel;

        public void Initialised(object context)
        {
            workbook = context as Workbook;
        }


        public System.Drawing.Bitmap ShowPanelImage { get { return (Resources.ev3).ToBitmap(); } }


        public bool RibbonVisible
        {
            get { return ribbonVisible; }
            set
            {
                ribbonVisible = value;
                OnPropertyChanged(() => RibbonVisible);
            }
        }


        public void CurrentViewChanged(object currentView)
        {
            RibbonVisible = workbook != null;
            panelShown = workbook != null;
        }

        public bool PanelShown
        {
            get { return panelShown; }
            set
            {
                if (panelShown == value) return;
                panelShown = value;
                ev3TaskPane.Visible = value;
                OnPropertyChanged(() => PanelShown);
            }
        }


        public void RegisterTaskPanes(Register register)
        {
            ev3TaskPane = register(() =>
            {
                mainPanel = new MainPanel() { Dock = System.Windows.Forms.DockStyle.Fill };
                mainPanel.CaptureToggle.Enabled = connected;
                mainPanel.ForwardButton.Enabled = connected;
                mainPanel.BackwardButton.Enabled = connected;

                mainPanel.ConnectToggle.CheckedChanged += (o, e) =>
                    {
                        if(mainPanel.ConnectToggle.Checked)
                        {
                            Task t = connect();
                            t.Wait();

                            mainPanel.CaptureToggle.Enabled = connected;
                            mainPanel.ForwardButton.Enabled = connected;
                            mainPanel.BackwardButton.Enabled = connected;

                        }
                        else
                        {
                            disconnect();
                            connected = false;
                            mainPanel.CaptureToggle.Enabled = connected;
                            mainPanel.ForwardButton.Enabled = connected;
                            mainPanel.BackwardButton.Enabled = connected;

                        }
                    };

                mainPanel.CaptureToggle.CheckedChanged += (o, e) =>
                    {
                        if (connected)
                        {
                            if (mainPanel.CaptureToggle.Checked)
                            {
                                sampleCount = 2;
                                ev3Brick.BrickChanged += ev3Brick_BrickChanged;

                            }
                            else
                            {
                                ev3Brick.BrickChanged -= ev3Brick_BrickChanged;
                            }
                        }
                    };
                mainPanel.ForwardButton.Click += (o, e) =>
                    {
                        if (connected)
                        {
                            Task t = move(Polarity.Forward);
                            t.Wait();
                        }
                    };
                mainPanel.BackwardButton.Click += (o, e) =>
                    {
                        if (connected)
                        {
                            Task t = move(Polarity.Backward);
                            t.Wait();
                        }
                    };

                var host = new System.Windows.Forms.UserControl
                {
                    Controls = { mainPanel }
                };

                host.Dock = System.Windows.Forms.DockStyle.Fill;
                host.BorderStyle = System.Windows.Forms.BorderStyle.None;
                return host;

            }, "PowerEV3");

            ev3TaskPane.DockPositionRestrict = MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNone;
            ev3TaskPane.DockPosition = MsoCTPDockPosition.msoCTPDockPositionLeft;
            ev3TaskPane.Visible = true;
            ev3TaskPane.VisibleChanged += TaskPaneVisibleChanged;
            TaskPaneVisibleChanged(this, EventArgs.Empty);
        }

        private int sampleCount = 2;
        private bool connected = false;

        private async Task connect()
        {
            ev3Brick = new Brick(new BluetoothCommunication("COM4"));

            await ev3Brick.ConnectAsync();

            connected = true;
        }

        private void disconnect()
        {
            if (ev3Brick != null)
                ev3Brick.Disconnect();
        }

        private async Task move(Polarity polarity)
        {
            ev3Brick.BatchCommand.PlayTone(0x50, 5000, 5000);
            ev3Brick.BatchCommand.SetMotorPolarity(OutputPort.B | OutputPort.C, polarity);
            ev3Brick.BatchCommand.TurnMotorAtSpeedForTime(OutputPort.A | OutputPort.B | OutputPort.C, 0x50, 5000, false);
            await ev3Brick.BatchCommand.SendCommandAsync();
        }


        void ev3Brick_BrickChanged(object sender, BrickChangedEventArgs e)
        {
            if (sampleCount == 52)
                sampleCount = 2;

            if(ev3Brick != null)
            {
                if (e.Ports[InputPort.Four].Type == DeviceType.Infrared)
                {
                    ((Worksheet)this.workbook.ActiveSheet).Range["E" + sampleCount.ToString()].Value2 = e.Ports[InputPort.Four].SIValue;
                }
                if (e.Ports[InputPort.B].Type == DeviceType.LMotor)
                {
                    ((Worksheet)this.workbook.ActiveSheet).Range["B" + sampleCount.ToString()].Value2 = e.Ports[InputPort.B].SIValue;
                }
                if (e.Ports[InputPort.C].Type == DeviceType.LMotor)
                {
                    ((Worksheet)this.workbook.ActiveSheet).Range["C" + sampleCount.ToString()].Value2 = e.Ports[InputPort.C].SIValue;
                }
                if (e.Ports[InputPort.A].Type == DeviceType.MMotor)
                {
                    ((Worksheet)this.workbook.ActiveSheet).Range["A" + sampleCount.ToString()].Value2 = e.Ports[InputPort.A].SIValue;
                }
                sampleCount++;
            };
        }
        public void Cleanup()
        {
            ev3TaskPane.VisibleChanged -= TaskPaneVisibleChanged;
        }


        private void TaskPaneVisibleChanged(object sender, EventArgs e)
        {
            panelShown = ev3TaskPane.Visible;
            OnPropertyChanged(() => PanelShown);
        }

    }
}
